Digital computers all have a supervisory program, known as an operating system, which controls the basic operations of the computer. It is the operating system which initially starts the computer operating when the computer is turned on. The operating system is a program that controls the execution of the programs that the user wishes to use, which are called application programs or simply applications. The operating system is usually invisible to the computer's user; it is the application program which the user actually observes running.
The operating system is usually designed to prevent the user from performing operations which are erroneous in some predesignated way. For example, the computer cannot divide a number by zero, since the result cannot be calculated. Such an erroneous operation generates a response known as an exception. If while running an application the operating system encounters an instruction which creates an exception, it will transfer control from the application which is being executed to a separate subroutine or program designed to handle that exception. These subroutines or programs are known as trap routines or trap handlers. Thus using the above example, if an application attempted to divide a number by zero, control of the computer would be transferred to a trap handler. Similarly, if an application tries to read from or write to a device or memory location which does not exist, the operating system will transfer control of the computer to a trap handler. Some trap handlers terminate the application program which is being executed, while others provide some type of warning message to the user.
A trap which occurs when an instruction attempts to perform some illegal operation is known as an exception trap. Exception traps can be very helpful to the computer's user, since exception traps catch inadvertent errors which may otherwise have gone unnoticed. Some such errors are otherwise undetectable by the user. Exception traps can be a hindrance, however, in cases where the application programmer knows that the exception will produce harmless results and that the instructions which create the exception are the best available for reaching that programmer's desired results.
For example, modern digital microprocessors can often perform mathematical functions much faster than they can access most commercially practical memory devices. To prevent idle processor time, programmers and optimizing compilers attempt to generate code that intersperses load instructions with computations performed on data already in the processor's internal registers. Ideally the program issues an instruction which loads data into an internal processor register and then proceeds with a calculation that involves only data currently in the internal registers. The load instruction is completed during the time period occupied by the subsequent computation. By the time the computation is completed, the data specified in the load instruction will be available for the next computation.
Consider a simple loop which add the contents of two arrays, A(i) and B(i), to produce a third array C(i)=A(i)+B(i). Here, i runs from 1 to N, where there are N elements in each of the arrays. The conventional method for coding such a loop produces code for the following operations:
(1) Load 1 into register i PA1 (2) Load A(i) into internal register x PA1 (3) Load B(i) into internal register y PA1 (4) Add the contents of x and y producing a result in internal register z PA1 (5) Store the contents of z in memory location C(i) PA1 (6) Increment register i and branch to (2) if i.ltoreq.N PA1 (1) Load 2 into register i PA1 (2) Load A(1) into register x PA1 (3) Load B(1) into register y PA1 (4) Add the contents of x and y to produce a result in register z PA1 (5) Load A(i) into register x PA1 (6) Load B(i) into register y PA1 (7) Store the contents of z at C(i-1) PA1 (8) Increment i PA1 (9) Branch to (4) if i.ltoreq.N+1
The above code contains two successive load instructions at steps (2) and (3), which must be completed before the instruction at step (4) can be executed. The processor must wait for the load instructions to be completed before performing the addition at step (4). During this time, the processor is idle.
The above example may be recoded in a manner that avoids much of the processor idle time as follows:
Here, the load instructions are interspersed with other instructions that can be executed while the load instructions are being completed. These loads are obtaining the values to be used in the next iteration of the loop of steps (4)-(9) in advance of actually performing the necessary addition. The problem with this method of coding the loop occurs at the last value of i. When i=N+1, the values of A(N+1) and B(N+1) will be requested. However, since there are only N elements in each of these arrays, there are no such elements in the arrays A and B. As a result, a memory exception may be generated which causes a trap. The trap handler may terminate the program, or produce some other undesirable result.
Since the contents of the illegal memory addresses are never actually used by the code, the memory violation is harmless. Unfortunately, prior art trap handlers routines have no means of ascertaining which memory violations are harmless.
One method that has been suggested for solving this problem involves defining two sets of instructions, normal instructions and dismissible instructions. An example of an instruction that might exist in both dismissible and non-dismissible forms is a load instruction. When a normal load instruction produces a trap condition, the trap operates normally. However, when a dismissible load instruction generates a trap condition, the condition is "dismissed" and the program resumes execution. Typically the dismissible instructions are distinguished from non-dismissible instructions by one bit of the instruction code. The computer hardware is designed to suppress a trap interrupt if the instruction generating the interrupt has the bit in question set to a predetermined value.
While this method of dealing with dismissible trap conditions allows the type of code described above to be used, it has a number of drawbacks. First, it can not be utilized on existing processors that do not implement these instructions in hardware. Since the indication of dismissibility of an instruction is contained in the instruction code and processed by the interrupt hardware, specially constructed processors must be utilized.
Second, two instructions must be provided for each operation that may generated a dismissible trap condition. This reduces the number of instructions that can be provided for any given instruction code length. If the instruction code length is increased to accommodate the new instructions, the amount of memory needed to store the program will increase or a fewer number of distinct operations can be described in the instruction set of the computer.
Third, the hardware designer must anticipate all instructions that may generate dismissible traps. Either the designer must be over-inclusive in designing the dismissible instruction set or the programmers will be limited in the code that can be run on the processor. If the designer is over-inclusive, processor hardware, and possible memory costs, will be increased due to increased hardware complexity. If the designer is under-inclusive, the programmer will be limited in his or her ability to provide efficient code for some task.
Finally, this approach does not allow the processor to make the decision on whether or not to dismiss an exception dependent upon the state of other registers in the processor. For example, it would be advantageous to allow the programmer to dynamically specify the dismissibility of certain classes of instructions during the execution of the code. This could be done by examining the contents of one or more registers in the computer and basing the dismissibility decision on the specific instruction causing the exception and the contents of these registers. Such conditional exception handling is difficult to implement in hardware without substantially increasing the complexity, and therefore cost, of the hardware.
Broadly, it is the object of the present invention to provide an improved method for operating a digital computer in response to an exception.
It is a further object of the present invention to provide a method of determining whether an instruction is dismissible which can be implemented on existing processors.
It is a still further object of the present invention to provide a method of operating a computer which allows a single instruction code to represent both dismissible and non-dismissible instructions which perform the same operation.
It is a yet further object of the present invention to provide a method of operating a computer which does not require that the hardware designer anticipate all instructions which may generate dismissible traps.
It is a still further object of the present invention to provide a method of operating a computer which allows the processor to determine dismissibility of an instruction in a manner that depends upon the status of computer registers or other hardware devices.
These and other objects of the present invention will be apparent to those skilled in the art from the following detailed description of the invention and the following drawings.